#!/bin/python3
# -*- coding: UTF-8
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.colors
import matplotlib.dates as mdates
from matplotlib.ticker import ScalarFormatter
from matplotlib.ticker import LogFormatter
from matplotlib.ticker import MultipleLocator
from matplotlib.ticker import FormatStrFormatter
from matplotlib.font_manager import findfont, FontProperties  
import matplotlib.font_manager as font_manager

from matplotlib.ticker import ScalarFormatter
from matplotlib.pyplot import MultipleLocator
from matplotlib import ticker
import common
import seaborn as sns
sns.set_theme()
# sns.set_style("white")
sns.set_theme(style="ticks")
sns.set_context("paper", font_scale=1.5)
plt.rcParams['xtick.direction'] = 'in'#将x的刻度线方向设置向内
plt.rcParams['ytick.direction'] = 'in'#将y的刻度方向设置向内
plt.rcParams['font.family']=['Sarasa Mono SC'] #用来正常显示中文标签
# plt.rcParams['axes.xmargin'] = 0
# plt.rcParams['axes.ymargin'] = 0

txt_alloc = "malloc内存请求延迟百分位"
txt_free = "free内存请求延迟百分位"
txt_executiontime = "内存请求延迟(μs)"


color_base_max = 1.0



colortbls = [	
		# (color_base_max * 13.0/14.0,  color_base_max* 13.0/14.0, color_base_max*13.0/14.0), 
		(color_base_max * 12.0/14.0,  color_base_max* 12.0/14.0, color_base_max*12.0/14.0), 
		(color_base_max * 11.0/14.0,  color_base_max* 11.0/14.0, color_base_max*11.0/14.0), 
		(color_base_max * 10.0/14.0,  color_base_max* 10.0/14.0, color_base_max*10.0/14.0),
		(color_base_max * 9.0/14.0,  color_base_max* 9.0/14.0, color_base_max*9.0/14.0),
		(color_base_max * 8.0/14.0,  color_base_max* 8.0/14.0, color_base_max*8.0/14.0),
		(color_base_max * 7.0/14.0,  color_base_max* 7.0/14.0, color_base_max*7.0/14.0),
		(color_base_max * 147/255,  color_base_max* 207/255, color_base_max*201/255),	# 无锁
		(color_base_max * 6.0/14.0,  color_base_max* 6.0/14.0, color_base_max*6.0/14.0),
		(color_base_max * 147/255,  color_base_max* 207/255, color_base_max*201/255),	# 无锁
		(color_base_max * 147/255,  color_base_max* 207/255, color_base_max*201/255),	# 无锁
		(color_base_max * 250/255,  color_base_max* 127/255, color_base_max*111/255),
		(color_base_max * 250/255,  color_base_max* 127/255, color_base_max*111/255),
		(color_base_max * 130/255,  color_base_max* 176/255, color_base_max*210/255),
		(color_base_max * 130/255,  color_base_max* 176/255, color_base_max*210/255),
		#(color_base_max * 231/255,  color_base_max* 218/255, color_base_max*210/255),
		(color_base_max * 190/255,  color_base_max* 184/255, color_base_max*220/255),
		(color_base_max * 250/255,  color_base_max* 127/255, color_base_max*111/255),
		]

lib_list = ['sys', 	'hd', 'tc', 'je', 	'lp', 	'tbb', 'rp', 'mesh', 'mi', 	'sn', 'wfspan', 'wfspan_wfqp', 'tlsf', 'tlsf_sffwd', 'hslab', 'wfslab']
markers = ['x', 	'h', 	'v', 	'<', 	'>', 	's', 	'+', 	'd', 	'o', 	'D', 	'^', 	'+',		'h', 	'x', 		'd', 	'o', 'D', 'h']
# bencn_baseline = 'wfslab'


def read_data(file_path):
	data = np.loadtxt(file_path,dtype=str,delimiter=' ')
	# print (data)
	return data

def get_test_data(data, allocator_name):
	ret = data[data[:, 0] == allocator_name]
	# 裁减

	x_series = data[0, 1:]
	# print (x_series.astype(float))
	return x_series, ret[:, 1:].astype(float)


def get_test_data_x_y(data, allocator_name):
	x_name, y = get_test_data(data, allocator_name)
	x_num = np.unique(x_name).size
	# print (x_name)
	# x_name_row = int(x_name.size / x_num)
	# x_name = x_name.reshape(x_name_row, x_num)

	# print (x_name)
	# y = y[:, column].astype(typ)
	# y = np.array(y)

	# y = y.reshape(x_name_row, x_num)
	# y.
	return x_name, np.mean(y, axis=0), np.std(y, axis=0)

def calculate_data(data, allocator_name_lists):
	ry = []
	ry_std = []

	for allocator in allocator_name_lists:
		tx, ty, tstd = get_test_data_x_y(data, allocator)
		ry.append(ty)
		ry_std.append(tstd)

	rx = tx
	ry = np.array(ry)
	ry_std = np.array(ry_std)
	return rx, ry, ry_std

def calculate_data(data, allocator_name_lists):
	ry = []
	ry_std = []

	for allocator in allocator_name_lists:
		tx, ty, tstd = get_test_data_x_y(data, allocator)
		# yx, yy, ystd = get_test_data_x_y(data2, allocator)
		ry.append(ty)
		ry_std.append(tstd)

	rx = tx
	ry = np.array(ry)
	ry_std = np.array(ry_std)
	return rx, ry, ry_std

def plot_subfig_avg(data_x, data_avg_y, data_std, axs, ylimit):
	xticks = data_x.astype(float)
	i = 0
	# print (xticks)
	# print ( data_avg_y[i])

	for label in lib_list:
		# print(label)
		# print(data_avg_y[i])
		# axs.errorbar(xticks, data_avg_y[i], yerr = data_std[i],  color=colortbls[i%len(lib_list)], alpha = 0.667,  capsize=2)
		axs.plot(xticks, data_avg_y[i], color=colortbls[i], label=label, marker=markers[i%len(lib_list)], markerfacecolor='none', markersize = 4)
		i+=1

def set_axs_label(axs, data_x, data_avg_y, rects, xlabel, ylabel, ylimit, use_log):
	xticks = data_x.astype(float) 
	# print (xticks)
	axs.set_xscale("logit")
	axs.set_yscale("log")
	axs.yaxis.set_major_formatter(ticker.ScalarFormatter())
	axs.set_xticks(xticks)
	axs.set_xticklabels((np.round(xticks*100.0, 6)).astype(str))
	# print ((np.array(xticks_name).astype(np.float64)*100).astype(str))
	axs.set_xlabel(xlabel)
	axs.set_ylabel(ylabel)

	axs.get_yaxis().get_major_formatter().set_scientific(False)
	axs.set_ylim(ylimit)

def plot_x86_arm(data_x, data_avg_y, data_std, data_avg_y_arm, data_std_arm, xlabel, xlabel1, ylabel, ylimit, scale):
	fig, axs = plt.subplots(nrows=1, ncols=2, figsize=(9, 2))
	# plt.xticks(rotation=120)
	data_avg_y = np.true_divide(data_avg_y ,scale)
	data_std = np.true_divide(data_std ,scale)
	data_avg_y_arm = np.true_divide(data_avg_y_arm ,scale)
	data_std_arm = np.true_divide(data_std_arm ,scale)

	rects = plot_subfig_avg(data_x, data_avg_y, data_std, axs[0], ylimit)
	set_axs_label(axs[0], data_x, data_avg_y, rects, xlabel, ylabel, ylimit, 1)
	axs[0].minorticks_off()

	rects = plot_subfig_avg(data_x, data_avg_y_arm, data_std_arm, axs[1], ylimit)
	set_axs_label(axs[1], data_x, data_avg_y_arm, rects, xlabel1, "", ylimit, 1)
	axs[1].minorticks_off()

	plt.legend(loc='upper center', bbox_to_anchor=(-0.11, 1.5), frameon=False, labelspacing = 0.1, handletextpad=0.2, columnspacing = 1, ncol= len(lib_list)/2 )
	# plt.tick_params(axis='y', which='minor')
	matplotlib.pyplot.subplots_adjust(left=0.08, right = 0.98, bottom = 0.22, top = 0.79, wspace = 0.10 )
	return fig, axs
# x86
data = read_data('./wcet_alloc_core13700k.tsv')
data = data[:, :-1]
alloc_x, alloc_y, alloc_std = calculate_data(data, lib_list)
print('malloc percentiles')
print (alloc_y)
data = read_data('./wcet_free_core13700k.tsv')
data = data[:, :-1]
aarch64_alloc_x, aarch64_alloc_y, aarch64_alloc_std = calculate_data(data, lib_list)
print('free ercentiles')
print (aarch64_alloc_y)
plot_x86_arm(alloc_x, alloc_y, alloc_std, aarch64_alloc_y, aarch64_alloc_std, txt_alloc, txt_free, txt_executiontime, (-1, 1000), 1000 )
# matplotlib.pyplot.subplots_adjust(left=0.06, right = 0.99, bottom = 0.12, top = 0.90, wspace = 0.10 )
plt.savefig("./fig/"+"wcet_13700k.pdf", format = "pdf")

# x86
data = read_data('./wcet_alloc_ryzen3700x.tsv')
data = data[:, :-1]
alloc_x, alloc_y, alloc_std = calculate_data(data, lib_list)
print('malloc percentiles')
print (alloc_y)
data = read_data('./wcet_free_ryzen3700x.tsv')
data = data[:, :-1]
aarch64_alloc_x, aarch64_alloc_y, aarch64_alloc_std = calculate_data(data, lib_list)
print('free ercentiles')
print (aarch64_alloc_y)
plot_x86_arm(alloc_x, alloc_y, alloc_std, aarch64_alloc_y, aarch64_alloc_std, txt_alloc, txt_free, txt_executiontime, (-1, 1000), 1000 )
# matplotlib.pyplot.subplots_adjust(left=0.06, right = 0.99, bottom = 0.12, top = 0.90, wspace = 0.10 )
plt.savefig("./fig/"+"wcet_3700x.pdf", format = "pdf")


#
data = read_data('./wcet_alloc_sdm888p.tsv')
data = data[:, :-1]
alloc_x, alloc_y, alloc_std = calculate_data(data, lib_list)
print('malloc percentiles')
print (alloc_y)
data = read_data('./wcet_free_sdm888p.tsv')
data = data[:, :-1]
aarch64_alloc_x, aarch64_alloc_y, aarch64_alloc_std = calculate_data(data, lib_list)
print('free ercentiles')
print (aarch64_alloc_y)
plot_x86_arm(alloc_x, alloc_y, alloc_std, aarch64_alloc_y, aarch64_alloc_std, txt_alloc, txt_free, txt_executiontime, (-1, 1000), 1000 )
# matplotlib.pyplot.subplots_adjust(left=0.06, right = 0.99, bottom = 0.12, top = 0.90, wspace = 0.10 )
plt.savefig("./fig/"+"wcet_888p.pdf", format = "pdf")
# plot_x86_arm(free_x, free_y, free_std, aarch64_free_y, aarch64_free_std, 'free请求延迟百分位', '请求延迟 (μs)', (-1, 1100), 1000)

# matplotlib.pyplot.subplots_adjust(left=0.06, right = 0.99, bottom = 0.15, top = 0.93, wspace = 0.10 )


# data = read_data('../api/test/wcettest_memreqout.csv')

# req_x, req_y, req_std = calculate_data(data, lib_list)

# data = read_data('../api/test/wcettest_memreqout_arm.csv')

# aarch64_req_x, aarch64_req_y, aarch64_req_std = calculate_data(data, lib_list)


# plot_x86_arm(req_x, req_y, req_std, aarch64_req_y, aarch64_req_std, '百分位数(%)', '请求执行时间(纳秒)', (-1024, 1000*1000) )

# plot_x86_arm(alloc_x, alloc_y, alloc_std, aarch64_alloc_y, aarch64_alloc_std, '百分位数(%)', '请求执行时间(纳秒)', (-1024, 1024 * 1024) )

# plot_x86_arm(free_x, free_y, free_std, aarch64_free_y, aarch64_free_std, '百分位数(%)', '请求执行时间(纳秒)', (-1024, 1024 * 1024) )

plt.show()